#pragma once
#include <Windows.h>
#include <string>
#include <map>
#include "tinyxml2.h"
#include "CTimer.h"
#include "ALEstd.h"
#include "ProcessManager.h"
#include "GameLogic.h"
#include "EventManagerImpl.h"
#include "D3D9Renderer.h"
#include "CInput.h"
#include "FmodAudio.h"
#include "LuaManager.h"

class Application
{
public:
	Application();
	virtual ~Application() { }

	virtual TCHAR *VGetGameTitle() = 0;
	virtual BaseGame* VCreateGame() = 0; 

	virtual bool VInitialize(HINSTANCE hInstance, LPTSTR lpCmdLine, HWND hWnd = NULL);
	virtual void VUpdate();
	virtual void VShutdown();
	virtual void VClose();

	void RunMainLoop();
	static LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

	bool LoadStrings(std::string language);
	std::wstring GetString(std::wstring sID);

	HWND GetHWND() const { return m_hWnd; }
	int GetScreenWidth() const { return m_screenWidth; }
	int GetScreenHeight() const { return m_screenHeight; }
	int GetColorDepth() const { return m_colorDepth; }
	bool IsFullscreen() const { return m_bFullscreen; }
	std::string GetLanguage() const { return m_language; }

	void SetScreenWidth(int value) { m_screenWidth = value; }
	void SetScreenHeight(int value) { m_screenHeight = value; }
	void SetColorDepth(int value) { m_colorDepth = value; }
	void SetFullscreen(bool value) { m_bFullscreen = value; }
	void SetLanguage(std::string value) { m_language = value; }

	Audio* GetAudio() const { return m_pAudio; }

protected:
	bool CreateGameWindow();

protected:
	std::map<std::wstring,std::wstring> m_textResource;

protected:
	HINSTANCE m_hInstance;
	HWND m_hWnd;
	bool m_bRunning;
	int m_screenWidth, m_screenHeight;
	int m_colorDepth;
	bool m_bFullscreen;
	int m_coreRefreshTime; //in ms
	std::string m_language;

	CTimer m_coreTimer;
	BaseGame *m_pGame;
	EventManager *m_pEventMgr;
	DXRenderer *m_pRenderer;
	CInput *m_pInput;
	Audio *m_pAudio;

};

extern Application *g_pApp;